#pragma once
#include <Windows.h>
#include "../windows.h"

#ifdef _WIN32
#ifdef _DEBUG
   #include <crtdbg.h>
   #undef THIS_FILE
//   static char THIS_FILE[] = __FILE__;
   #define new       new( _NORMAL_BLOCK, __FILE__, __LINE__)
   #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif

namespace acme {
  namespace scratch {

    //
    struct Rect;
    struct String;

    //

    class Application; // A class that wraps up application concepts
    class Thread;      // A class that encapsulates an os thread.
    class STApplication; // A class that implements an application with an STA apartment

    class Window;      // A class that wraps a window (desktop level window)
    class View;        // A class that wraps a view object (content in a window)
    class Popup;       // A class that wraps a modal or modeless content window

    class Trace;      // A class for managing debugging traces.

    // Delegates
    struct ApplicationDelegate;
    struct WindowDelegate;

    //////////////////////////////////////////////////////////////////////////////////////////////

    struct Rect : RECT
    {
      Rect(int x, int y, int w, int h){
        left = x;
        top = y;
        right = x+w;
        bottom = y+h;
      }
      Rect(){}
    };

    typedef LPCTSTR string;

    struct String
    {
      LPCTSTR psz; 

      String();
    };


    //////////////////////////////////////////////////////////////////////////////////////////////



        


    struct ApplicationDelegate
    {
      virtual void applicationDidFinishLaunching(){}
      virtual void applicationWillTerminate(){}
    };

    struct WindowDelegate
    {
      virtual void windowDidResize(int width,int height){}
      virtual void windowDidMove(){}
      virtual void windowDidUpdate(){}
      virtual BOOL windowShouldClose(){return TRUE;}
      virtual void windowDidClose(){}
      virtual void windowTimer(int id){}
    };

    class Application {
    };

    class STApplication : public Application {
    public:
      static int Main(ApplicationDelegate* delegate);
    };

    class Window
    {
      HWND _hwnd;
      WindowDelegate* _delegate;
      View* _content;
      static LRESULT CALLBACK WindowProcThunk(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
      virtual LRESULT WindowProc(UINT uMsg,WPARAM wParam,LPARAM lParam);
      void Create(int x, int y, int w, int h,string windowTitle);
      void Show();
      void Send(UINT uMsg);
    protected:

    public:
      Window();
      ~Window();
      void initWithContentRect(Rect frame);
      void makeKeyAndOrderFront();
      void performClose();
      void setContentView(View*);
      void setDelegate(WindowDelegate* delegate);
      HWND hwnd(){
        return _hwnd;
      }
    };


    class View
    {
    protected:
      HWND _hwnd;
    protected:
      View():_hwnd(0){}
      ~View(){}
    };

    class CustomView : public View
    {
    };


    class Trace
    {
    public:
      static void Write(string message);
      static void WriteFormat(string message,...);
      static void Warn(string message);
      static void WarnFormat(string message,...);
    };



  }
}
